package calao;

import java.util.HashMap;
import java.util.Vector;

import calao.storage.EqualCondition;
import calao.storage.Field;
import calao.storage.Record;
import calao.storage.Search;
import calao.storage.Sequence;
import calao.storage.Table;
import calao.util.Cursor;
import calao.util.Strings;

public class User {

	static final Table TABLE = new Table("calao.User"); 

	static final Sequence ID_SEQUENCE = new Sequence("calao.UserId");

	static final Field<Integer> ID = 
		TABLE.createField("id", Field.INTEGER);	

	static final Field<String> ALIAS = 
		TABLE.createField("alias", Field.STRING);	

	static final Field<String> EMAIL = 
		TABLE.createField("email", Field.STRING);	

	static final Field<String> PASSWORD_HASH = 
		TABLE.createField("phash", Field.STRING);	

	static {
		TABLE.createPrimaryKeyIndex(ID);
		TABLE.createIndex(ALIAS);
	}
	
	final Server server;
	final int wsid;
	final int id;
	String alias;
	String email;
	String passwordHash;
	
	User(Workspace ws, Record rec)
	{
		this(ws, rec.getInt(ID), rec.get(ALIAS), rec.get(EMAIL));
		passwordHash = rec.get(PASSWORD_HASH);
	}
	
	User(Workspace ws, int id, String alias, String email)
	{
		this.server = ws.server;
		this.wsid = ws.id;
		this.id = id;
		this.alias = alias;
		this.email = email;
	}
	
	static int getUID(long guid) {
		return (int)(guid&0xFFFFFFFF);
	}
	
	static int getUWSID(long guid) {
		return (int)(guid>>32);
	}
	
	static long toGUID(int uwsid, int uid) {
		return (((long)uwsid)<<32)|((long)uid);
	}
	
	long getGlobalUserId()
	{
		return toGUID(wsid, id);
	}
	
	public void save()
	{
		getWorkspace().getUserManager().store(id, alias, passwordHash, email);			
	}

	public String getAlias() {
		return alias;
	}

	public String getEmail() {
		return email;
	}
	
	public void setPassword(String password)
	{
		passwordHash = Strings.md5Hash(password);
	}
	
	public Membership[] getMemberships()
	{
		Search search = new Search(Membership.TABLE);
		search.add(new EqualCondition(Membership.GLOBAL_USER_ID, getGlobalUserId()));
		Vector<Membership> result = new Vector<Membership>();
		Cursor<Record> cursor = getWorkspace().server.storage.listResults(search);
		try {
			while (cursor.next()) {
				Record rec = cursor.get();
				int mwsid = rec.getInt(Membership.WORKSPACE_ID);
				Membership mship = new Membership(server.getWorkspace(mwsid), rec);
				result.add(mship);
			}
		}
		finally {
			cursor.close();
		}
		return result.toArray(new Membership[result.size()]);
	}

	public void setAlias(String alias) {
		this.alias = alias;
	}

	public void setEmail(String email) {
		this.email = email;
	}
	
	public Membership createMembership(Workspace ws, String name, int[] profiles)
	{
		return ws.getMembershipManager().createMembership(
				getGlobalUserId(), name, profiles);
	}
		
	public Membership createMembership(Workspace ws, String name, int[] profiles,
			HashMap<String,String> properties)
	{
		return ws.getMembershipManager().createMembership(
				getGlobalUserId(), name, profiles, properties);
	}
	
	public Workspace getWorkspace()
	{
		return server.getWorkspace(wsid);
	}

}
